import cfg from "@/utils/config.js"
import vanNotify from '@/wxcomponents/vant/notify/notify.js'
import CryptoJS from '@/utils/crypto-js.js'
const isTest = cfg.isTest,
	domain = cfg.domain,
	config = {
		URLS: {
			login: domain + "wxmini/hxtlogin",
			getUser: domain + 'wxmini/miniCurrentUser',
			abcLogin: domain + 'wxmini/abcLogin',
			miniIsSubscribe: domain + 'wxmini/miniIsSubscribe',
			// 账号关联				
			unbind: domain + 'wxmini/hxtunbind',
			bind: domain + 'wxmini/hxtbind',
			// 已收信息
			msgrecv: domain + 'wxmini/hxtmsgrecv',
			msgdetail: domain + 'wxmini/hxtmsgdetail',
			// 已发信息
			msgsend: domain + 'wxmini/hxtmsgsend',
			msgsendobjs: domain + 'wxmini/hxtmsgsendobjs',
			// 发信息
			msgmenu: domain + 'wxmini/hxtmsgmenu',
			msgobj: domain + 'wxmini/hxtmsgobj',
			msgnew: domain + 'wxmini/hxtmsgnew',
			// 工资
			wages: domain + 'wxmini/miniwages',
			// 独立密码
			defexists: domain + 'wxmini/miniDefExists',
			defvalid: domain + 'wxmini/miniDefValid',
			defsms: domain + 'wxmini/miniDefSms',
			defsmsvalid: domain + 'wxmini/miniDefSmsValid',
			defsave: domain + 'wxmini/miniDefSave',
			//假条
			leavelist: domain + 'wxmini/miniLeaveList', //假条列表

			leaveopt: domain + 'wxmini/miniLeaveOpt' //假条审批
				,
			leavestudent: domain + 'wxmini/miniLeaveStudentList' //批假班级学生列表
				,
			leavesave: domain + 'wxmini/miniLeaveSave' //请假|批假 保存
				,
			leavesta: domain + 'wxmini/miniLeaveSTA' // 请假人次统计
				,
			leavestadetail: domain + 'wxmini/miniLeaveSTADetail' // 请假人次统计 明细
				//成绩
				,
			examlist: domain + 'wxmini/miniExamList' // 成绩列表
				,
			examteacherdetail: domain + 'wxmini/miniExamTeacherDetail' // 教师成绩明细
				,
			examteachersta: domain + 'wxmini/miniExamTeacherSTA' // 综合统计
				,
			examTeacherSTAABC: domain + 'wxmini/miniExamTeacherSTAABC' //等级统计
				,
			examstudentdetail: domain + 'wxmini/miniExamStudentDetail' // 学生成绩明细
				//教师通讯录
				,
			addrbook: domain + 'wxmini/miniAddrBook', // 学生成绩明细
			//课表
			timetable: domain + 'wxmini/miniTimeTable', // 课表				
			timecheckin: domain + 'wxmini/miniTimeCheckIn', // 课表考勤记录				
			timechecksta: domain + 'wxmini/miniTimeCheckInSTAT', // 课表考勤统计				
			timecheckdetail: domain + 'wxmini/miniTimeCheckInDetail', // 课表考勤明细
			timeCheckInChangeStatus: domain + 'wxmini/wxTimeCheckInChangeStatus', // 课表考勤明细
			//考勤				
			checkinmenu: domain + 'wxmini/miniCheckInMenu' // 考勤统计菜单
				,
			checkinClassDetail: domain + 'wxmini/miniCheckInClassDetail' // 班级考勤明细
				,
			checkinSchoolSta: domain + 'wxmini/miniCheckInSchoolSta' // 学校统计
				,
			checkinGradeSta: domain + 'wxmini/miniCheckInGradeSta' // 年级统计
				,
			checkinTeacherDetail: domain + 'wxmini/miniCheckInTeacherDetail' // 教师考勤
				,
			checkinUserDetail: domain + 'wxmini/miniCheckInUserDetail' // 个人考勤明细
				,
			checkinHandSign: domain + 'wxmini/miniCheckInHandSign', // 手签
			//会议				
			meetingTeacherGroup: domain + 'wxmini/miniMeetingTeacherGroup', // 会议新增 教师组/人脸设备 列表				
			meetingMeetingTeacherGroupPerson: domain + 'wxmini/miniMeetingTeacherGroupPerson', // 会议新增 教师组成员				
			meetingNew: domain + 'wxmini/miniMeetingNew', // 会议新增				
			meetingList: domain + 'wxmini/miniMeetingList', // 会议列表				
			meetingSignList: domain + 'wxmini/miniMeetingSignList', // 会议签到详情				
			meetingOpt: domain + 'wxmini/miniMeetingOpt', // 取消会议 | 提前结束
			//一卡通充值
			cardOrder: domain + 'wxmini/miniCardOrder', // 一卡通充值下单				
			cardHistoryList: domain + 'wxmini/miniCardHistoryList', // 一卡通充值记录				
			cardList: domain + 'wxmini/miniCardList', // 一卡通消费流水				
			cardLoss: domain + 'wxmini/miniCardloss', // 一卡通挂失
			teacherPhotoObjList: domain + 'wxmini/teacherPhotoObjList', //教师采照片 班级或学生列表
			teacherSavePhoto: domain + 'wxmini/teacherSavePhoto', //教师采照片 保存学生照片
			saveConsumePwd: domain + 'wxmini/saveConsumePwd', //保存消费密码
			//通知缴费
			autoTList: domain + 'wxmini/miniAutoTList', // 教师已发收费通知列表				
			autoList: domain + 'wxmini/miniAutoList', // 家长接收到的收费通知列表
			autoSendDetail: domain + 'wxmini/miniAutoSendDetail', // 教师已发收费通知明细
			autoHistoryList: domain + 'wxmini/miniAutoHistoryList' // 家长获取收费通知交费历史
				,
			autoPayDetail: domain + 'wxmini/miniAutoPayDetail' // 家长收费通知明细
				,
			autoOrder: domain + 'wxmini/miniAutoOrder' // 收费通知下单
				,
			autoRejectDo: domain + 'wxmini/miniAutoRejectDo' // 家长收费通知退单
				,
			autoRejectList: domain + 'wxmini/miniAutoRejectList' // 家长收费通知退单记录
				,
			autoRejectListCancel: domain + 'wxmini/miniAutoRejectListCancel' // 取消退单申请
				,
			autoDelNofity: domain + 'wxmini/miniAutoDelNofity' // 删除收费通知
				,
			autoConfirmNotify: domain + 'wxmini/miniAutoConfirmNotify', // 确认发送收费通知
			autoClassPersonList: domain + 'wxmini/miniAutoClassPersonList', // 获取收费通知班级成员列表
			autoRejectListSendWithID: domain + 'wxmini/miniAutoRejectListSendWithID', // 教师查询退单情况

			autoNewPage: domain + 'wxmini/miniAutoNewPage' // 教师发新通知初始
				,
			autoCreateNew: domain + 'wxmini/miniAutoCreateNew' // 新收费通知数据
				,
			autoEditSave: domain + 'wxmini/miniAutoEditSave' // 收费通知编辑保存
				,
			autoNewSave: domain + 'wxmini/miniAutoNewSave' // 收费通知新增保存
				,
			autoAccount: domain + 'wxmini/miniAutoAccount', // 收费通知账户
			//功能费充值
			payunifiedorder: domain + 'wxmini/unifiedorder', // 统一下单
			payOrderUpdate: domain + 'wxmini/wxOrderUpdate', // 微信支付订单更新
			payCardpay: domain + 'wxmini/miniCardpay', // 充值卡充值
			payDailySearch: domain + 'wxmini/miniDailySearch', //充值代缴 查询
			payDailyDic: domain + 'wxmini/miniDailyDic', //充值代缴 充值面额
			//服务订购
			UserSelfChangePkgList: domain + 'wxmini/UserSelfChangePkgList', //获取用户已订购的服务
			UserSelfChangePkg: domain + 'wxmini/UserSelfChangePkg', //用户订购功能包
			//晨午晚检			
			tiwenInit: domain + 'wxmini/miniTiwenInit', // 页面初始
			tiwenTimeSave: domain + 'wxmini/miniTiwenTimeSave', // 时段保存
			tiwenSTAT: domain + 'wxmini/miniTiwenSTAT', // 统计
			tiwenHand: domain + 'wxmini/miniTiwenHand', // 手工登记
			//学平险
			xpxList: domain + 'wxmini/miniXpxList', //学平险
			//新生注册
			userRegInit: domain + 'wxmini/userRegInit', //初始 获取学校和班级
			sendUserRegCode: domain + 'wxmini/sendUserRegCode', //发送注册验证码
			userReg: domain + 'wxmini/userReg', //注册
			//访客登记
			visitConfig: domain + 'wxmini/visitConfig', //访客配置
			visitInfo: domain + 'wxmini/visitInfo', //访客记录
			visitList: domain + 'wxmini/visitList', //访客记录列表
			visitSave: domain + 'wxmini/visitSave', //访客记录新增
			visitConfirm: domain + 'wxmini/visitConfirm', //访客记录核验
			visitConfigSave: domain + 'wxmini/visitConfigSave', //访客配置保存
			//应用
			getAppMsg: domain + 'wxmini/getAppMsg', //应用消息
			//公共
			pubMasterClassList: domain + 'wxmini/miniMasterClassList', //班级列表 班主任				
			leaveclass: domain + 'wxmini/miniLeaveClassList', //班级列表全部
			osssign: domain + 'wxmini/ossToken',
			baiduToken: domain + 'wxmini/baiduToken', //百度云accessToken
			mediaupload: domain + 'wxmini/hxtmediaupload',
			//采照片
			oiphotoobj: domain + 'wxmini/oiPhotoObjList',
			oisavephoto: domain + 'wxmini/oiSavePhoto',
			//报告流程
			oamixedlist: domain + 'wxmini/oaMixedList', //报告流程列表
			oamixeddetail: domain + 'wxmini/oaMixedDetail', //报告流程明细
			oanextoptor: domain + 'wxmini/oaNextOptor', //查询下一处理人员
			oadeal: domain + 'wxmini/oaDeal', //处理
			//计费中心 费用明细
			oarefundmoney: domain + 'wxmini/oaRefundMoneyDetail', //退款明细
			oadeferrecord: domain + 'wxmini/oaDeferRecordDetail', //延期明细
			oatransactfree: domain + 'wxmini/oaTransactFreeDetail', //免费明细
			oasharecharge: domain + 'wxmini/oaShareChargeDetail', //费用共享明细
			oareturnrecord: domain + 'wxmini/oaReturnRecordDetail', //费用返还明细
			oalargessrecharge: domain + 'wxmini/oaLargessRechargeDetail', //赠送充值明细
			oaeraserecord: domain + 'wxmini/oaEraseRecordDetail', //欠费抹除明细
			oaagencyfeesettling: domain + 'wxmini/oaAgencyFeeSettlingDetail', //分润结算明细
			oapauseDate: domain + 'wxmini/oaPauseDateDetail', //延期临停明细
			oabatchPay: domain + 'wxmini/oaBatchPayDetail', //批量充值明细
			//免费短信
			oafreeSMSlist: domain + 'wxmini/oaFreeSMSList', //列表
			oafreeSMSdetail: domain + 'wxmini/oaFreeSMSDetail', //详情
			oadealfreeSms: domain + 'wxmini/oaDealFreeSms',
			//系统监控、
			oagetinterfaceMenu: domain + 'wxmini/oaGetInterfaceMenu', //获取接口菜单
			oagetinterfaceSTA: domain + 'wxmini/oaGetInterfaceSTA', //获取接口统计数据
			oagetdeductfeeMsg: domain + 'wxmini/oaGetDeductFeeMsg', //获取计费信息
			//导号码权限
			oaexportschool: domain + 'wxmini/oaExportSchool', //单个学校列表
			oaexportschoolbatch: domain + 'wxmini/oaExportSchoolBatch', //多个学校的学校列表
			oaexportoptor: domain + 'wxmini/oaExportOptor', //操作人列表
			oaexportclass: domain + 'wxmini/oaExportClass', //授权对象列表
			oaexportsave: domain + 'wxmini/oaExportSave', //单个学校保存
			oaexportsavebatch: domain + 'wxmini/oaExportSaveBatch' //多个学校保存
				, //消费合同余额
			schoollist: domain + 'wxmini/oa70503SchoolList', //学校列表
			sellerlist: domain + 'wxmini/oa70503SellerList', //商家列表
			subjectlist: domain + 'wxmini/oa70503SubjectList', //消费科目列表
			oaSTAbalancestate: domain + 'wxmini/oaSTABalanceState', //统计消费合同余额
			//设备管理
			oadeviceschool: domain + 'wxmini/oaDeviceSchool', //学校列表
			oadevicelist: domain + 'wxmini/oaDeviceList', //设备列表
			oadeviceadd: domain + 'wxmini/oaDeviceAdd', //添加设备
			oadevicedetail: domain + 'wxmini/oaDeviceDetail', //设备明细
			oadeviceupdate: domain + 'wxmini/oaDeviceUpdate', //修改设备
			//考勤记录
			oafuncnolist: domain + 'wxmini/oaFuncNoList', //功能号列表
			oaattreceivemsg: domain + 'wxmini/oaAttReceiveMsg', //考勤记录
			//提醒
			oaT2o: domain + 'wxmini/oaT2o', //教师助理提醒
			oaSg2o: domain + 'wxmini/oaSg2o', //留言提醒
			//共享空间
			sfGetFiles: domain + 'web/sfGetFiles', //列表
			sfGetAccessUsers: domain + 'web/sfGetAccessUsers', //授权成员列表
			sfSaveFile: domain + 'web/sfSaveFile', //保存文件/文件夹
			sfSaveDelete: domain + 'web/sfSaveDelete', //删除文件/文件夹
			sfGetTotal: domain + 'web/sfGetTotal', //获取空间大小
			sfGetFileLink: domain + 'web/sfGetFileLink', //获取下载地址

			//宿管
			checkByUserSchedule: domain + 'dorm/checkByUserSchedule', //考勤表（月）
			dormCheckByUserCardList: domain + 'dorm/dormCheckByUserCardList', //考勤明细

			selectList: domain + 'adminNew/selectList', //考勤组列表
			classInfoList: domain + 'dorm/classInfoList', //年级、班级列表
			userSearchInSchoolFull: domain + 'dorm/userSearchInSchoolFull', //学校用户检索
			dormBuidingList: domain + 'dorm/dormBuidingList', //楼栋列表
			dormFloorList: domain + 'dorm/dormFloorList', //楼层列表
			dormRoomList: domain + 'dorm/dormRoomList', //宿舍列表
			roomUserAssign: domain + 'dorm/roomUserAssign', //退宿

			dormSTAT: domain + 'dorm/dormSTAT', //宿管考勤统计
			dormAttendanceResultList: domain + 'dorm/dormAttendanceResultList', //宿管每日考勤结果

			dormBuidingStatistics: domain + 'dorm/dormBuidingStatistics', //楼栋统计
			dormFloorStatistics: domain + 'dorm/dormFloorStatistics', //楼层统计
			dormRoomAndUserList: domain + 'dorm/dormRoomAndUserList', //宿舍人员列表
			roomCheckSave: domain + 'dorm/roomCheckSave', //巡查保存

			dormRepairsList: domain + 'dorm/dormRepairsList', //报修列表
			dormRepairsSave: domain + 'dorm/dormRepairsSave', //报修保存
			//学生信息
			oiStudentList: domain + 'adminNew/studentList', //学生列表
			oiSelectList: domain + 'adminNew/selectList',
			oiStudentDel: domain + 'adminNew/studentDelete', //删除学生
			oiStudentInfo: domain + 'adminNew/studentInfo', //学生信息
			userSavePhone: domain + 'adminNew/userSavePhone', //保存号码
			userSyncDaikou: domain + 'adminNew/userSyncDaikou', //同步代扣状态
			userSaveEmail: domain + 'adminNew/userSaveEmail', //保存邮件
			userChangeStatus: domain + 'adminNew/userChangeStatus', //改变服务状态
			studentChangeReject: domain + 'adminNew/studentChangeReject', //改变拒绝代扣状态
			userNotify: domain + 'adminNew/userNotify', //发通知
			userXPOpenCard: domain + 'adminNew/userXPOpenCard', //校智付开卡
			userSaveOnlyWXList: domain + 'adminNew/userSaveOnlyWXList', //信息接收方式保存
			studentUpdate: domain + 'adminNew/studentUpdate', //学生信息修改
			userSaveUEI: domain + 'adminNew/userSaveUEI', //保存扩展信息
		},
		PAGES: [
			//家校互动
			{
				state: 'sendhistory',
				name: '已发信息',
				icon: '',
				badge: 0,
				img: '/static/images/menu/msgsend.png',
				url: '/hxt/msg/msgsend'
			}, {
				state: 'recvhistory',
				name: '已收信息',
				icon: '',
				badge: 0,
				img: '/static/images/menu/msgrecv.png',
				url: '/hxt/msg/msgrecv',
				user: true
			}, {
				state: 'newmsg',
				name: '发新信息',
				icon: '',
				badge: 0,
				img: '/static/images/menu/msgnew.png',
				url: '/hxt/msg/msgnew',
				user: true
			}, {
				state: 'recvmsgdetail',
				url: '/hxt/msg/msgrecvdetail',
				user: true
			}, {
				state: 'schoolnotice',
				name: '学校公告',
				icon: 'fa fa-bullhorn bg-green',
				badge: 0,
				img: '',
				url: '/notify/schoolnotice/index',
				user: true
			}, {
				state: 'schoolnotifyadd',
				url: '/notify/schoolnotice/add',
				user: true
			}, {
				state: 'noticedetail',
				url: '/notify/schoolnotice/detail',
				user: true
			}, {
				state: 'classnotify',
				name: '班级通知',
				icon: 'fa fa-bell-o bg-green',
				badge: 0,
				img: '',
				url: '/notify/classnotify/index',
				user: true
			}, {
				state: 'classnotifyadd',
				url: '/notify/classnotify/add',
				user: true
			}, {
				state: 'notifydetail',
				url: '/notify/classnotify/detail',
				user: true
			}
			//我的
			, {
				state: 'wages',
				name: '我的工资',
				icon: '',
				badge: 0,
				img: '/static/images/menu/wages.png',
				url: '/hxt/my/wages'
			}, {
				state: 'pay',
				name: '互学通充值',
				icon: '',
				badge: 0,
				img: '/static/images/menu/pay.png',
				url: '/hxt/my/pay/pay',
				user: true
			} // 功能费充值
			, {
				state: 'leave',
				name: '请假',
				icon: '',
				badge: 0,
				img: '/static/images/menu/leave.png',
				url: '/hxt/my/leave/leave'
			}, {
				state: 'exam',
				name: '成绩',
				icon: '',
				badge: 0,
				img: '/static/images/menu/exam.png',
				url: '/hxt/my/score/score',
				user: true
			}, {
				state: 'checkin',
				name: '考勤',
				icon: '',
				badge: 0,
				img: '/static/images/menu/checkin.png',
				url: '/hxt/my/attendance'
			}, {
				state: 'addrbook',
				name: '教师通讯录',
				icon: '',
				badge: 0,
				img: '/static/images/menu/addrbook.png',
				url: '/hxt/my/mailList'
			}, {
				state: 'sttable',
				name: '课表',
				icon: '',
				badge: 0,
				img: '/static/images/menu/sttable.png',
				url: '/hxt/my/Timetable'
			}
			//会议
			, {
				state: 'meeting',
				name: '会议通知',
				icon: '',
				badge: 0,
				img: '/static/images/menu/meeting.png',
				url: '/hxt/meeting/notice'
			}, {
				state: 'meetinghistory',
				name: '参会记录',
				icon: '',
				badge: 0,
				img: '/static/images/menu/meetinghistory.png',
				url: '/hxt/meeting/record'
			}
			//一卡通充值
			, {
				state: 'occard',
				name: '一卡通充值',
				icon: '',
				badge: 0,
				img: '/static/images/menu/occard.png',
				url: '/hxt/card/recharge',
				user: true
			}, {
				state: 'occardhistory',
				name: '充值记录',
				icon: '',
				badge: 0,
				img: '/static/images/menu/occardhistory.png',
				url: '/hxt/card/recharge-record',
				user: true
			}, {
				state: 'occardlist',
				name: '消费记录',
				icon: '',
				badge: 0,
				img: '/static/images/menu/occardlist.png',
				url: '/hxt/card/record',
				user: true
			}, {
				state: 'userphoto',
				name: '门禁照片管理',
				icon: 'cuIcon-camerafill bg-cyan',
				badge: 0,
				img: '',
				url: '/hxt/oi/userphoto',
				user: true
			}, {
				state: 'singlephoto',
				name: '门禁照片管理',
				icon: 'cuIcon-profile bg-cyan',
				badge: 0,
				img: '',
				url: '/hxt/oi/singlephoto',
				user: true
			}, {
				state: 'occonsumepwd',
				name: '消费密码',
				icon: 'fa fa-key bg-cyan',
				badge: 0,
				img: '',
				url: '/hxt/card/occonsumepwd',
				user: true
			},
			//宿舍管理
			{
				state: 'dormcheckinlist',
				name: '考勤记录',
				icon: 'cuIcon-form bg-mauve',
				badge: 0,
				img: '',
				url: '/dorm/dormcheckinlist',
				user: true
			},
			{
				state: 'dormdetail',
				name: '住宿情况',
				icon: 'fa fa-bed bg-mauve',
				badge: 0,
				img: '',
				url: '/dorm/dormdetail',
				user: true
			},
			{
				state: 'dormsta',
				name: '考勤统计',
				icon: 'fa fa-area-chart bg-mauve',
				badge: 0,
				img: '',
				url: '/dorm/dormsta',
				user: true
			},
			{
				state: 'dormcheck',
				name: '查寝',
				icon: 'fa fa-check-square-o bg-mauve',
				badge: 0,
				img: '',
				url: '/dorm/dormcheck',
				user: true
			},
			{
				state: 'dormrepair',
				name: '报修',
				icon: 'fa fa-wrench bg-mauve',
				badge: 0,
				img: '',
				url: '/dorm/dormrepair',
				user: true
			},
			//通知缴费
			{
				state: 'ocauto',
				name: '通知缴费',
				icon: '',
				badge: 0,
				img: '/static/images/menu/ocauto.png',
				url: '/hxt/Other/teacher/noticesend',
				user: true
			}, {
				state: 'ocautonew',
				name: '发新通知',
				icon: '',
				badge: 0,
				img: '/static/images/menu/ocautonew.png',
				url: '/hxt/Other/teacher/noticenew',
				user: true
			}, {
				state: 'ocautoaccount',
				name: '我的账户',
				icon: '',
				badge: 0,
				img: '/static/images/menu/ocautoaccount.png',
				url: '/hxt/Other/parent/MyAccount',
				user: true
			}, {
				state: 'ocautohistory',
				name: '缴费记录',
				icon: '',
				badge: 0,
				img: '/static/images/menu/ocautohistory.png',
				url: '/hxt/Other/parent/PaymentRecord',
				user: true
			}, {
				state: 'ocautorejectlist',
				name: '退单记录',
				icon: '',
				badge: 0,
				img: '/static/images/menu/ocautorejectlist.png',
				url: '/hxt/Other/parent/Chargeback',
				user: true
			}, {
				state: 'ocautopay',
				url: '/hxt/msg/msgrecvdetail',
				user: true
			},
			//应用
			{
				state: 'appmsg',
				url: '/hxt/third/appmsg/appmsg',
				user: false
			},
			{
				state: 'tiwen',
				name: '晨（午、晚）检',
				icon: 'fa fa-thermometer-half bg-blue',
				badge: 0,
				img: '',
				url: '/hxt/third/tiwen/tiwen',
				user: false
			},
			{
				state: 'myxpx',
				name: '学平险',
				icon: 'fa fa-american-sign-language-interpreting bg-blue',
				badge: 0,
				img: '',
				url: '/hxt/third/myxpx/myxpx',
				user: false
			},
			{
				state: 'sharedspace',
				name: '共享空间',
				icon: 'fa fa-share-alt bg-blue',
				badge: 0,
				img: '',
				url: '/hxt/third/sharedspace/sharedspace',
				user: false
			},
			{
				state: 'ynupper',
				name: '',
				icon: 'fa fa-external-link bg-blue',
				badge: 0,
				img: '',
				url: '',
				user: false
			},
			{
				state: 'visit',
				name: '访客登记',
				icon: 'fa fa-id-card-o bg-blue',
				badge: 0,
				img: '',
				url: '/hxt/third/visit/visit?type=2',
				user: false
			}, {
				state: 'visitnew', //访客登记新增
				url: '/hxt/third/visit/visitnew',
				user: false,
				noUser: true
			}, {
				state: 'userreg',
				url: '/hxt/third/userreg/userreg',
				user: false,
				noUser: true
			},
			//内部办公
			{
				state: 'oaReport',
				icon: 'cuIcon-circle bg-gradual-blue',
				badge: 0,
				name: '报告流程',
				url: '/optor/Report/index'
			},
			{
				state: 'oaReportDetail',
				url: '/optor/Report/detail'
			},
			{
				state: 't2o',
				url: '/optor/oi/t2o'
			},
			{
				state: 'sg2o',
				url: '/optor/oi/sg2o'
			},
			{
				state: 'oaSystemMonitoring',
				icon: 'cuIcon-record bg-gradual-blue',
				badge: 0,
				name: '系统监控',
				url: '/optor/Monitor/index'
			}, {
				state: 'oaExportPhone',
				icon: 'cuIcon-safe bg-gradual-blue',
				badge: 0,
				name: '导号码权限',
				url: '/optor/PilotNumber/index'
			}, {
				state: 'oaFreeSms',
				icon: 'cuIcon-comment bg-gradual-blue',
				badge: 0,
				name: '免费短信',
				url: '/optor/FreeSMS/index'
			}, {
				state: 'oaDevice',
				icon: 'cuIcon-repair bg-gradual-blue',
				badge: 0,
				name: '设备管理',
				url: '/optor/Equipment/index'
			}, {
				state: 'oaAttReceiveMsg',
				icon: 'cuIcon-calendar bg-gradual-blue',
				badge: 0,
				name: '考勤记录',
				url: '/optor/Attendance/index'
			}, {
				state: 'oa70503',
				icon: 'cuIcon-redpacket bg-gradual-blue',
				badge: 0,
				name: '消费余额合同',
				url: '/optor/Balance/index'
			}, { //采照片
				state: 'oiphoto',
				name: '采照片',
				icon: 'cuIcon-camera bg-gradual-blue',
				badge: 0,
				img: '',
				url: '/optor/oi/userphoto'
			},
			{
				state: 'oiMain',
				name: '学生信息',
				icon: 'cuIcon-camera bg-gradual-blue',
				badge: 0,
				img: '',
				url: '/optor/oi/oiMain'
			},
			//mall
			{
				state: 'mall',
				name: '优享活动',
				icon: 'fa fa-paw bg-blue',
				badge: 0,
				img: '',
				url: '/mall/index',
				user: false
			}, {
				state: 'suborder',
				url: '/mall/suborder',
				user: false,
				noUser: true
			}, {
				state: 'addgood',
				url: '/mall/addgood',
				user: false,
				noUser: false
			},
			//mall/pickup 接送服务
			{
				state: 'pickup',
				name: '接送服务',
				icon: 'fa fa-bus bg-blue',
				badge: 0,
				img: '',
				url: '/mall/pickup/index'
			},
			{
				state: 'pickupbind',
				name: '',
				url: '/mall/pickup/bind',
				noUser: true
			}, //绑定路线

			{
				state: 'pclogin',
				name: '',
				url: '/pages/index/pclogin',
				noUser: true
			}
		]
	};
/**
 * 判断是否Function(o:any) => true/false
 * @param {any} o
 */
const isFunction = function(o) {
	return Object.prototype.toString.call(o) == '[object Function]';
};
/**
 * 判断是否数组(o:any) => true/false
 * @param {any} o
 */
const isArray = function(o) {
	return Object.prototype.toString.call(o) == '[object Array]';
};
const isNullOrUndefined = function(o) {
	var s = Object.prototype.toString.call(o);
	return s == '[object Null]' || s == '[object Undefined]';
};

const log = function() {
	isTest && console.log.call(console, ...arguments);
};
/**
 * 移除字符串前后空白字符
 * @param {String} text 
 */
const trim = function(text) {
	var trimLeft = /^[\s\uFEFF\xA0]+/;
	var trimRight = /[\s\uFEFF\xA0]+$/;
	return text == null ? "" : (text + "").replace(trimLeft, "").replace(trimRight, "");
};
/**
 * 判断是否手机号码
 * @param {String}} text 
 */
const isMobile = function(text) {
	return /^(134|135|136|137|138|139|147|150|151|152|157|158|159|165|172|178|182|183|184|187|188|195|197|198|130|131|132|145|155|156|166|167|170|171|175|176|185|186|196|133|149|153|162|173|177|180|181|189|190|191|192|193|199)\d{8}$/
		.test(text);
};
/**
 * 生成算数验证码 返回：{code:运算结果, text:运算表达式文本}
 */
const createNumCode = function() {
	var o = {
		code: 0,
		text: ''
	};
	var num1 = Math.floor(Math.random() * 9) + 1;
	var num2 = Math.floor(Math.random() * 9) + 1;
	var tmparith = Math.floor(Math.random() * 3);
	switch (tmparith) {
		case 1:
			o.code = num1 + num2;
			o.text = num1 + ' + ' + num2 + ' = ？'
			break;
		case 2:
			if (parseInt(num1) < parseInt(num2)) {
				var tmpnum = num1;
				num1 = num2;
				num2 = tmpnum;
			}
			o.code = num1 - num2;
			o.text = num1 + ' - ' + num2 + ' = ?';
			break;
		default:
			o.code = num1 * num2;
			o.text = num1 + ' × ' + num2 + ' = ?';
			break;
	}
	return o;
};
/**
 * md5加密 32位小写
 * @param {any} string 
 */
const ToMd5 = function(string) {
	return CryptoJS.MD5(string).toString().toLowerCase();
};
//显示loading
const showLoading = function(msg) {
	//hideLoading();
	wx.showLoading({
		title: msg || '请稍后...',
		mask: true
	});
};
//隐藏loading
const hideLoading = function() {
	setTimeout(() => {
		wx.hideLoading();
	}, 0);
};
/**
 * 弹出提示框
 * @param {String} msg 提示的文字
 * @param {String} title 提示的标题
 * @param {Function} ok 点击确定的回调函数
 */
var alert = function(msg, title, ok) {
	wx.showModal({
		title: title || '提示',
		content: msg,
		confirmColor: '#00B1FF',
		showCancel: false,
		success: function(res) {
			if (res.confirm == true) {
				isFunction(ok) && ok();
			}
		}
	});
};
/**
 * 弹出确认框
 * @param {String} msg 提示的文字
 * @param {String} title 提示的标题
 * @param {Function} ok 点击确定的回调函数
 */
var confirm = function(msg, title, ok, fail) {
	wx.showModal({
		title: title || '提示',
		content: msg,
		confirmColor: '#00B1FF',
		showCancel: true,
		cancelText: '取消',
		cancelColor: '#888',
		success: function(res) {
			if (res.confirm == true) {
				isFunction(ok) && ok();
			} else {
				isFunction(fail) && fail();
			}
		}
	});
};
/**
 * toast提示
 * @param {String} msg 提示文字，7个汉字内
 * @param {String} icon 有效值：none, success, error
 */
const toast = function(msg, icon) {
	wx.showToast({
		title: msg,
		icon: icon || 'none',
		mask: true
	});
};
/**
 * toast成功提示
 * @param {String} msg 提示文字，7个汉字内
 */
const toastOK = function(msg) {
	toast(msg, 'success');
};
/**
 * toast失败提示
 * @param {String} msg 提示文字，7个汉字内
 */
const toastERR = function(msg) {
	toast(msg, 'error');
};
const getPage = function() {
	const pages = getCurrentPages();
	return pages.length > 0 ? pages[pages.length - 1] : null;
};
/**
 * 显示/隐藏遮罩
 * 需要在页面放置组件 \<hxt-loading id="hxt-loading">\</hxt-loading>
 * @param {Boolean} isLoading 
 */
const loading = function(isLoading) {
	const context = getPage();
	var layout = !!context ? context.selectComponent('#hxt-layout') : null;
	const loading = !!layout ? layout.selectComponent('#hxt-loading') : context.selectComponent('#hxt-loading');
	if (!!loading) {
		// console.log(loading);
		loading.setData({
			display: isLoading == false ? false : true
		});
		// loading.display=isLoading == false ? false : true;  // 将组件的 myProperty 属性设置为 '新的值'
		// loading.$vm.display = isLoading == false ? false : true;
	};
};
/**
 * 统一post请求
 * @param {object} option {url:请求地址, data:数据, ok({code, errmsg, url}):请求成功时的回调函数, fail(res):请求失败的回调函数, addApp:是否增加app数据，默认是，为0时不增加, mask:自定义遮罩方法, unmask:自定义关闭遮罩方法，showMask：是否显示遮罩，为 false 时不显示}
 */
const post = function(option) {
	if (!option || !option.url) {
		alert('missing parameter');
		return;
	};
	if (!option.responseType) option.responseType = 'text';
	const app = getApp();
	const showMask = option.showMask != false;
	if (showMask) {
		if (!option.mask) {
			option.mask = function() {
				loading();
			};
		}
		if (!option.unmask) {
			option.unmask = function() {
				loading(false);
			};
		}
	}
	showMask && isFunction(option.mask) && option.mask();
	if (option.addApp != 0 && typeof option.data === 'object' && !!app.globalData.appInfo) {
		option.data.key = app.globalData.currentUser.openId;
		option.data.reqType = 1;
	}
	log(option);
	var header = {
		"content-type": "application/x-www-form-urlencoded",
		'__publish': cfg.isPublish ? '' : 'test',
		'__req': 1,
		'__key': ''
	};
	if (!!app.globalData.appInfo) header['__key'] = app.globalData.appInfo.key;
	wx.request({
		url: option.url,
		data: option.data,
		header: header,
		responseType: option.responseType,
		method: "POST",
		success: function(res) {
			log(res);
			isFunction(option.ok) && option.ok(res);
		},
		fail: function(res) {
			if (isFunction(option.fail)) {
				option.fail(res);
				return;
			}
			alert(res, '出错了');
		},
		complete: function() {
			showMask && isFunction(option.unmask) && option.unmask();
		}
	});
};
/**
 * 生成guid
 * @param {Boolean} separator 是否添加分隔符“-”，为 false 时不添加
 */
const guid = function(separator) {
	function S4() {
		return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
	}
	return [S4() + S4(), S4(), S4(), S4(), S4() + S4() + S4()].join(separator == false ? '' : '-');
}
/**
 * 统一文件上传
 * @param {*} option {path:本地路径, ok(res):请求成功时的回调函数, fail(res):请求失败的回调函数, mask:遮罩方法, unmask:关闭遮罩方法}
 */
const uploadfile = function(option) {
	if (!option || !option.path) {
		alert('missing parameter path');
		return;
	}
	var checkUser = option.checkUser === false ? false : true;
	const app = getApp();
	if (!app.globalData.appInfo || (checkUser && !app.globalData.currentUser)) {
		alert('missing login info');
		return;
	}
	const showMask = option.showMask != false;
	if (showMask) {
		if (!option.mask) {
			option.mask = function() {
				loading();
			};
		}
		if (!option.unmask) {
			option.unmask = function() {
				loading(false);
			};
		}
	}
	showMask && isFunction(option.mask) && option.mask();

	var now = Date.parse(new Date()) / 1000,
		uploadToServer = function() {
			wx.uploadFile({
				url: config.URLS.mediaupload, //此处换上你的接口地址  
				filePath: option.path,
				name: 'hxtfile',
				header: {
					"Content-Type": "multipart/form-data"
				},
				method: "POST",
				formData: {
					key: app.globalData.appInfo.key,
					uiId: !app.globalData.currentUser ? 0 : app.globalData.currentUser.uiId
				},
				success: function(res) {
					log(res);
					var data = JSON.parse(res.data);
					if (data.code != 0) {
						option.fail({
							errMsg: '[uploadToServer code ' + data.code + ']' + data.errmsg
						});
						return;
					}
					isFunction(option.ok) && option.ok({
						data: data
					});
				},
				fail: function(res) {
					if (isFunction(option.fail)) {
						option.fail({
							errMsg: '[uploadToServer fail]' + res.errMsg
						});
						return;
					}
					alert(res.errMsg, '出错了');
				},
				complete: function() {
					isFunction(option.unmask) && option.unmask();
				}
			});
		},
		callFail = function(msg) {
			if (!!option.uptoserver) {
				uploadToServer();
				return;
			} else {
				isFunction(option.unmask) && option.unmask();
				var res = {
					errMsg: msg
				};
				if (isFunction(option.fail)) {
					option.fail(res);
					return;
				}
				alert(res.errMsg, '出错了');
			}
		},
		callUpload = function() {
			var index = option.path.lastIndexOf('.');
			var oss = app.globalData.oss,
				key = oss.key + '/' + (!!option.name ? option.name : guid(false) + option.path.substring(index)
					.toLowerCase());
			// key = oss.key + '/' + guid(false);
			wx.uploadFile({
				url: oss.host,
				filePath: option.path,
				name: 'file',
				formData: {
					key: key,
					policy: oss.policy,
					OSSAccessKeyId: oss.accessKeyId,
					signature: oss.signature,
					success_action_status: oss.success_action_status
				},
				success: function(res) {
					//log('oss upload result', res);
					if (res.statusCode === oss.success_action_status) {
						isFunction(option.unmask) && option.unmask();
						isFunction(option.ok) && option.ok({
							data: {
								code: 0,
								errmsg: null,
								url: oss.host + '/' + key
							}
						});
					} else {
						callFail('[upload statusCode ' + res.statusCode + ']' + res);
					}
				},
				fail: function(res) {
					callFail('[upload fail]' + res.errMsg);
				}
			});
		};
	if (!app.globalData.oss || (app.globalData.oss.expire || 0) - 90 < now) { //签名过期
		post({
			showMask: false,
			url: domain + 'pc/v3OssToken',
			data: {
				folder: option.ossKey
			},
			ok: function(res) {
				if (res.data.code != 0) {
					option.uptoserver = false;
					callFail('[sign code ' + res.data.code + ']' + res.data.errmsg);
					return;
				}
				app.globalData.oss = res.data;
				callUpload();
			},
			fail: function(res) {
				option.uptoserver = false;
				callFail('[sign fail]' + res.errMsg);
			}
		});
	} else {
		callUpload();
	}
};

const getAppInfo = function(options, ok) {
	var data = {
		req: 0,
		key: null,
		exp: 0,
		state: '',
		user: 0,
		id: 0,
		code: 0,
		errmsg: null
	};
	const app = getApp();
	// wx.clearStorage();
	var appInfo = wx.getStorageSync('appInfo');
	if (!!appInfo) {
		data.req = appInfo.req;
		data.key = appInfo.key;
		data.exp = appInfo.exp;
		data.state = appInfo.state;
		data.user = appInfo.user;
		data.id = appInfo.id;
	}

	if (!!options) {
		if (!!options.state) data.state = options.state;
		if (!!options.user) data.user = options.user;
		if (options.id == 0 || !!options.id) data.id = options.id;
		if (options.req == 0 || !!options.req) {
			if (data.req != options.req) {
				data.exp = 0;
				data.req = options.req;
			}
		}
	}

	var callBack = function(code, errmsg) {
		data.code = code;
		data.errmsg = errmsg;
		wx.setStorageSync('appInfo', data);
		app.globalData.appInfo = data;
		isFunction(ok) && ok(data);
	};

	// callBack(0,'11111');
	// return;

	var now = Date.parse(new Date()) / 1000;
	var loadUser = function(query) {
		wx.removeStorageSync('state');
		post({
			showMask: true,
			addApp: 0,
			url: domain + 'home/WxMpLogin',
			data: query,
			ok: function(x) {
				// console.log(x.data);
				if (x.data.code != 0) {
					callBack(x.data.code, x.data.errmsg);
					return;
				}
				data.key = x.data.key;
				data.exp = now + 30 * 24 * 60;
				app.globalData.currentUser = x.data.data;
				// store.loginInfo.update({ key: x.data.key, userList: x.data.userList, currentUser: x.data.currentUser });
				callBack(0, null);
			},
			fail: function(x) {
				console.log(x, 'xxx')
				callBack(-3, x.errMsg);
			}
		});
	};
	if (now > data.exp || !data.key) { //登录过期
		wx.login({
			success: function(res) {
				console.log(res)
				if (!!res.code) {
					loadUser({
						code: res.code,
						req: data.req,
						key: data.key,
						user: data.user,
						state: data.state,
						id: data.id
					});
				} else {
					callBack(-2, '[wx.login]' + res.data);
				}
			},
			fail: function(res) {
				callBack(-1, '[wx.login]' + res.errMsg);
			}
		});
		return;
	}
	loadUser({
		req: data.req,
		key: data.key,
		user: data.user,
		state: data.state,
		id: data.id
	});
};
/**
 * 获取用户信息文本描述 姓名/班级/学校
 * @param {object} user
 */
const getUserDes = function(user) {
	var arr = [];
	if (!!user) {
		if (!!user.uiName) arr.push('-' + user.uiName);
		if (!!user.className) arr.push('/' + user.className);
		if (!!user.schoolName) arr.push('/' + user.schoolName);
	}
	return arr.join('');
};

var padRight = function(str, n, chr) {
	if (!chr) chr = ' ';
	var val = (!str ? '' : str) + '';
	var len = val.length;
	while (len < n) {
		val = val + chr;
		len++;
	}
	return val;
};
const checkSchoolSets = function(sets, n) {
	if (n <= 0 || n > 64) return false;
	var val = padRight(sets, 64, '0');
	//console.log(val, val.substring(n - 1, n));
	return val.substring(n - 1, n) == '1';
};

function formatBit(val) { // 补0
	val = +val
	return val > 9 ? val : '0' + val
}
/**
 * 秒转时分秒 返回 hh:mm:ss 格式
 * @param {Number} s 秒
 */
const formatSeconds = function(s) { // 秒转时分秒，求模很重要，数字的下舍入
	let min = Math.floor(s % 3600);
	let h = Math.floor(s / 3600);
	let val = h > 0 ? formatBit(h) + ':' : '';
	val += formatBit(Math.floor(min / 60)) + ':' + formatBit(parseInt(s % 60));
	return val;
}
/**
 * 字节转 KB MB
 * @param {Number} s 字节
 */
const formatSize = function(s) {
	var kb = (Math.round(s * 100 / 1024) / 100);
	if (kb < 1024) return kb + 'KB';
	return (Math.round(kb * 100 / 1024) / 100) + 'MB';
};


const isSameWeek = function(date) { //判断是否本周
	var self = this;
	if (isNullOrUndefined(date)) return false;
	date = toDate(date);
	if (date == null) return false;
	let inDateStr = date.toLocaleDateString(); // 获取如YYYY/MM/DD的日期
	let nowDate = new Date();
	let nowTime = nowDate.getTime();
	let nowDay = nowDate.getDay();
	for (let i = 0; i < 7; i++) {
		if (inDateStr == (new Date(nowTime + (i - nowDay) * 24 * 3600 * 1000)).toLocaleDateString())
			return true;
	}
	return false;
};


const dateFormat1 = function(date) { //本周格式化为：星期W；本年格式化为：MM/dd；往年格式化为：yyyy/MM/dd
	var _this = this,
		today = new Date();
	if (isNullOrUndefined(date)) return '';
	date = toDate(date);
	if (date == null) return '';
	if (date.getDate() === today.getDate() && date.getMonth() === today.getMonth() && date.getFullYear() === today
		.getFullYear()) return formatDateTime("HH:mm", date);
	if (isSameWeek(date)) return formatDateTime("星期W HH:mm", date);
	else if (!!date && date.getFullYear() == today.getFullYear()) return formatDateTime("MM/dd HH:mm", date);
	else return formatDateTime("yyyy/MM/dd HH:mm", date);
};


/**
 * 时间格式化
 * @param {fmt} YYYY-mm-dd HH:MM
 * * @param {date} date
 */
const dateFormat = function(fmt, date) {
	var ret;
	if (isNullOrUndefined(date)) date = new Date();
	else {
		date = toDate(date);
		if (date == null) return null;
	}
	const opt = {
		"y+": date.getFullYear().toString(), // 年
		"M+": (date.getMonth() + 1).toString(), // 月
		"d+": date.getDate().toString(), // 日
		"h+": date.getHours().toString(), // 时
		"m+": date.getMinutes().toString(), // 分
		"s+": date.getSeconds().toString() // 秒
		// 有其他格式化字符需求可以继续添加，必须转化成字符串
	};
	for (let k in opt) {
		ret = new RegExp("(" + k + ")").exec(fmt);
		if (ret) {
			fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
		};
	};
	return fmt;
}

/**
 * 查找数组中符合匹配条件的的第一个元素索引
 * => -1：未查找到符合条件的元素；>=0：符合条件的第一个元素在数组中的索引
 * @param {Array} arr 数组
 * @param {function} fn 过滤函数，接受一个参数，为当前迭代的数组元素，要求返回bool
 */
const findIndex = function(arr, fn) {
	var _this = this;
	if (!_this.isArray(arr) || !_this.isFunction(fn)) return -1;
	for (var i = 0; i < arr.length; i++) {
		if (!!fn(arr[i], i)) return i;
	}
	return -1;
};
/**
 * 查找数组中符合匹配条件的的第一个元素
 * => null：未查找到符合条件的元素；其它：符合条件的第一个元素
 * @param {Array} arr 数组
 * @param {function} fn 过滤函数，接受一个参数，为当前迭代的数组元素，要求返回bool
 */
const find = function(arr, fn) {
	var _this = this;
	var idx = _this.findIndex(arr, fn);
	return idx >= 0 ? arr[idx] : null;
};

/**
 * 查找数组中符合条件的对象 
 * => Array
 * @param {Array} arr 数组
 * @param {function} fn 过滤函数，接受2个参数，1 为当前迭代的数组元素, 2为当前迭代的数组元素索引，要求返回bool
 */
const findItems = function(arr, fn) {
	var newArr = [];
	if (!isArray(arr) || !isFunction(fn)) return newArr;
	for (var i = 0; i < arr.length; i++) {
		if (!!fn(arr[i], i)) newArr.push(arr[i]);
	}
	return newArr;
};

const extend = function(data, dataExtend) {
	var res = {};
	for (var key in data) {
		res[key] = data[key];
	}
	for (var key in dataExtend) {
		res[key] = dataExtend[key];
	}
	return res;
}

/*---------------------------------------------------  
* @date:2020/08/26
* @description：formatDateTime 日期时间格式化 
* @param {String} formatStr 预期格式 默认【yyyy-MM-dd HH:mm:ss】
* @param {Date/String} date 默认当前时间 传入类型为String时注意格式【yyyy-MM-dd HH:mm:ss  yyyy/MM/dd HH:mm:ss】
* @returns {String} 
* 预期格式说明：YYYY/yyyy/YY/yy 表示年份 MM/M 月份 W/w 星期 dd/DD/d/D 日期 hh/HH/h/H 时间 mm/m 分钟 ss/SS/s/S 秒
---------------------------------------------------*/
const formatDateTime = function(formatStr, date) {
	if (date == undefined) {
		date = new Date();
	} else if (typeof date === 'string') {
		//如果不是Date型做转换,失败则返回预期外的值,需注意
		var index = date.indexOf(".");
		if (index != -1) {
			date = date.substring(0, index); //解决IE下带毫秒时间转换出错
		}
		date = new Date(date.replace(/\-/g, '/'));
	}
	formatStr = (formatStr == undefined ? "yyyy-MM-dd HH:mm:ss" : formatStr);
	var str = formatStr;
	var Week = ['日', '一', '二', '三', '四', '五', '六'];
	str = str.replace(/yyyy|YYYY/, date.getFullYear());
	str = str.replace(/yy|YY/, (date.getYear() % 100) > 9 ? (date.getYear() % 100).toString() : '0' + (date
		.getYear() % 100));

	var month = date.getMonth() + 1; //获取当前月份(0-11,0代表1月)
	str = str.replace(/MM/, month > 9 ? month.toString() : '0' + month);
	str = str.replace(/M/g, month);

	str = str.replace(/w|W/g, Week[date.getDay()]);

	str = str.replace(/dd|DD/, date.getDate() > 9 ? date.getDate().toString() : '0' + date.getDate());
	str = str.replace(/d|D/g, date.getDate());

	str = str.replace(/hh|HH/, date.getHours() > 9 ? date.getHours().toString() : '0' + date.getHours());
	str = str.replace(/h|H/g, date.getHours());
	str = str.replace(/mm/, date.getMinutes() > 9 ? date.getMinutes().toString() : '0' + date.getMinutes());
	str = str.replace(/m/g, date.getMinutes());

	str = str.replace(/ss|SS/, date.getSeconds() > 9 ? date.getSeconds().toString() : '0' + date.getSeconds());
	str = str.replace(/s|S/g, date.getSeconds());

	return str;
};
/**
 * 指定日期时间上增减相应时间 
 * => Date
 * @param {String} interval 增加类型：y年 q季度 M月 w周 d天 h时 m分 s秒
 * @param {Number} number 增加值
 * @param {Date} date 基础值 Date格式，默认当前时间
 */
const addToDate = function(interval, number, date) {
	if (date == undefined) {
		date = new Date();
	} else if (typeof date === 'string') {
		//如果不是Date型做转换,失败则返回预期外的值,需注意
		date = new Date(date.replace(/\-/g, '/')); //replace(/\-/g, '/')修复IOS转换错误问题
	}
	switch (interval) {
		case "y": //年
		{
			date.setFullYear(date.getFullYear() + number);
			return date;
		}
		case "q": //季度
		{
			date.setMonth(date.getMonth() + number * 3);
			return date;
		}
		case "M": //月
		{
			date.setMonth(date.getMonth() + number);
			return date;
		}
		case "w": //周
		{
			date.setDate(date.getDate() + number * 7);
			return date;
		}
		case "d": //天
		{
			date.setDate(date.getDate() + number);
			return date;
		}
		case "h": //时
		{
			date.setHours(date.getHours() + number);
			return date;
		}
		case "m": //分
		{
			date.setMinutes(date.getMinutes() + number);
			return date;
		}
		case "s": //秒
		{
			date.setSeconds(date.getSeconds() + number);
			return date;
		}
		default: {
			date.setDate(date.getDate() + number);
			return date;
		}
	}
};

/*
 * 判断用户是否包含某个权限
 */
const hasAccessID = function(accId) {
	var app = getApp();
	if (!app.globalData.appInfo || !app.globalData.currentUser) {
		alert('missing login info');
		return;
	}
	var user = app.globalData.currentUser,
		has = false;
	if (!!user && user.teacherFn.length > 0) {
		var ix = user.teacherFn.indexOf(accId);
		if (ix > -1) has = true;
	}
	return has;
};

const Notify = function(option) {
	if (option == null || option == undefined) option = {};
	if (typeof option === 'string') option = {
		message: option
	};
	var context = getPage();

	var layout = !!context ? context.selectComponent('#hxt-layout') : null;
	var Notify = !!layout ? layout : context;
	option.context = Notify;
	option.selector = '.hxt-notify';
	vanNotify(option);
};

const error = function(msg, callback) {
	Notify({
		type: 'danger',
		message: msg
	});
	isFunction(callback) && callback();
};

const success = function(msg, callback) {
	Notify({
		type: 'success',
		message: msg,
		duration: 1000
	});
	isFunction(callback) && callback();
};

// base64解码函数
const base64Decode = function(input, safe) {
	var str = '' + input;
	str = str.replace(/\-/g, '+').replace(/_/g, '/');
	var len = str.Length % 4;
	if (len == 2) str += "==";
	else if (len == 3) str += "=";
	return CryptoJS.enc.Base64.parse(str).toString(CryptoJS.enc.Utf8);
}
const base64Encode = function(input, safe) {
	var str = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(input));
	if (true == safe) {
		str = str.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "")
	}
	return str;
}
/**
 * 手机号码验证
 */
const getPhoneType = function(val) {
	val = $.trim(val);
	if (val.length >= 7 && val.length <= 12) {
		if (val.length == 11) {
			if (val.substring(0, 1) == '0') return 3;
			else {
				val = val.substring(0, 3);
				if ('134,135,136,137,138,139,147,150,151,152,157,158,159,182,183,184,187,188,178,172,198,195,165'
					.split(',').indexOf(val) >= 0) return 0;
				else if ('130,131,132,145,155,156,185,186,176,170,171,175,166,167'.split(',').indexOf(val) >= 0)
					return 1;
				else if ('133,153,180,189,181,177,173,149,199,191,193,162,190'.split(',').indexOf(val) >= 0)
					return 2;
			}
		} else if (val.length == 7 || val.length == 8) {
			if (val.substring(0, 1) != '0') return 3;
		} else if (val.length == 12) {
			if (val.substring(0, 1) == '0') return 3;
		}
	}
	return -1;
}
const isEmail = function(val) {
	return /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/.test(val);
}

/**
 * 验证身份证
 * => Boolean
 * @param {any} code
 */
const isIdentityCode = function(code) {
	var city = {
		11: "北京",
		12: "天津",
		13: "河北",
		14: "山西",
		15: "内蒙古",
		21: "辽宁",
		22: "吉林",
		23: "黑龙江 ",
		31: "上海",
		32: "江苏",
		33: "浙江",
		34: "安徽",
		35: "福建",
		36: "江西",
		37: "山东",
		41: "河南",
		42: "湖北 ",
		43: "湖南",
		44: "广东",
		45: "广西",
		46: "海南",
		50: "重庆",
		51: "四川",
		52: "贵州",
		53: "云南",
		54: "西藏 ",
		61: "陕西",
		62: "甘肃",
		63: "青海",
		64: "宁夏",
		65: "新疆",
		71: "台湾",
		81: "香港",
		82: "澳门",
		91: "国外"
	};

	if (!code || !
		/(^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{2}[0-9Xx]$)/i
		.test(code)) {
		return false;
	} else if (!city[code.substr(0, 2)]) {
		return false;
	} else {
		if (code.length == 18) {
			code = code.split('');
			var factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
			var parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2];
			var sum = 0;
			for (var i = 0; i < 17; i++) {
				sum += code[i] * factor[i];
			}
			if (parity[sum % 11] != code[17].toUpperCase()) {
				return false;
			}
		}
	}
	return true;
}
/**
 * 验证是否日期
 * @param {any} val
 */
const isDate = function(val) {
	return Object.prototype.toString.call(val) == '[object Date]';
}
/**
 * 转换为日期，错误返回 null
 * @param {any} val
 */
const toDate = function(val) {
	if (isDate(val)) return val;
	if (typeof val === 'string' && !!val) {
		var index = val.indexOf(".");
		if (index != -1) {
			val = val.substring(0, index); //解决IE下带毫秒时间转换出错
		}
		var date = new Date(val.replace(/\-/g, '/'));
		if (isNaN(date)) return null;
		return date;
	}
	return null;
}
/**
 * 指定日期时间上增减相应时间 
 * => Date
 * @param {String} interval 增加类型：y年 q季度 M月 w周 d天 h时 m分 s秒
 * @param {Number} number 增加值
 * @param {Date} date 基础值 Date格式，默认当前时间
 */
const dateAdd = function(interval, number, date) {
	if (isNullOrUndefined(date)) date = new Date();
	else {
		date = toDate(date);
		if (date == null) return null;
	}
	switch (interval) {
		case "y": //年
		{
			date.setFullYear(date.getFullYear() + number);
			return date;
		}
		case "q": //季度
		{
			date.setMonth(date.getMonth() + number * 3);
			return date;
		}
		case "M": //月
		{
			date.setMonth(date.getMonth() + number);
			return date;
		}
		case "w": //周
		{
			date.setDate(date.getDate() + number * 7);
			return date;
		}
		case "d": //天
		{
			date.setDate(date.getDate() + number);
			return date;
		}
		case "h": //时
		{
			date.setHours(date.getHours() + number);
			return date;
		}
		case "m": //分
		{
			date.setMinutes(date.getMinutes() + number);
			return date;
		}
		case "s": //秒
		{
			date.setSeconds(date.getSeconds() + number);
			return date;
		}
		default: {
			date.setDate(date.getDate() + number);
			return date;
		}
	}
}
/**
 * 获取日期
 * @param {any} val
 */
const dateConfig = function(val) {
	var date = null;
	if (isNullOrUndefined(val)) date = new Date();
	else {
		date = toDate(val);
		if (date == null) return {};
	}
	var o = {
		monthBegin: dateFormat('yyyy-MM-01', date),
		monthEnd: '',
		nextMonthBegin: dateFormat('yyyy-MM-01', dateAdd('M', 1, new Date(date))),
		nextMonthEnd: '',
		lastMonthBegin: dateFormat('yyyy-MM-01', dateAdd('M', -1, new Date(date))),
		lastMonthEnd: '',
		today: dateFormat('yyyy-MM-dd', date),
		monthDays: new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate(),
		year: date.getFullYear(),
		month: date.getMonth() + 1,
		day: date.getDate(),
		week: date.getDay()
	};
	o.week = o.week == 0 ? 7 : o.week;
	o.lastMonthEnd = dateFormat('yyyy-MM-dd', dateAdd('d', -1, o.monthBegin));
	o.nextMonthEnd = dateFormat('yyyy-MM-dd', dateAdd('d', -1, dateAdd('M', 1, o.nextMonthBegin)));
	o.monthEnd = dateFormat('yyyy-MM-dd', dateAdd('d', -1, o.nextMonthBegin));
	return o;
}
/**
 * 时间戳转换
 */
const timestampToTime = function(timestamp) {
	// 时间戳为10位需*1000，时间戳为13位不需乘1000
	var date = new Date(timestamp * 1000);
	var Y = date.getFullYear() + "-";
	var M =
		(date.getMonth() + 1 < 10 ?
			"0" + (date.getMonth() + 1) :
			date.getMonth() + 1) + "-";
	var D = (date.getDate() < 10 ? "0" + date.getDate() : date.getDate()) + " ";
	var h = date.getHours() + ":";
	var m = date.getMinutes() + ":";
	var s = date.getSeconds();
	return Y + M + D;
}
/**
 * 计算用户承担的手续费
 * @param {number} amount 实际金额
 * @param {number} brokerageRate 用户承担的手续费比率
 * @param {number} serviceRate 用户承担的服务费比率
 */
const wxBrokerage = function(amount, brokerageRate, serviceRate) {
	var data = {
		sum: 0,
		brokerage: 0,
		service: 0
	}; /*sum：要支付的金额；brokerage：手续费；service：服务费；*/
	var all = (amount * 100) / (1 - brokerageRate - serviceRate);
	data.sum = (Math.round(all) / 100).toFixed(2);
	data.brokerage = (Math.round(data.sum * 100 * brokerageRate) / 100).toFixed(2);
	data.service = ((data.sum * 100 - data.brokerage * 100 - amount * 100) / 100).toFixed(2);
	return data;
}
/**
 * 格式字符串数字
 * => {
		value: null/NaN/String, 格式化后的数字值 null：传入参数为空；NaN：传入参数不是数字
		isNum: true/false, 传入参数是否数字
		minus: true/false, 是否负数
		num: String, 整数部分的的值
		dec: String, 小数部分的值
		digit: Number 小数位数
	}
 * @param {any} n 
 */
const formatNum = function(n) {
	var data = {
		value: null,
		isNum: false,
		minus: false,
		num: '',
		dec: '',
		digit: 0
	};
	var s = (n || '').trim();
	if (s.length == 0) return data;
	var reg = /^(\-)?([0]+|[0]*[1-9][0-9]*)(\.[0-9]+)?$/;
	if (!reg.test(s)) {
		data.value = NaN;
		return data;
	}
	//移除小数点后多余的0和多余的小数点
	if (s.indexOf('.') > -1) {
		while (s.substr(s.length - 1, 1) == '0') {
			s = s.substr(0, s.length - 1);
		}
		if (s.substr(s.length - 1, 1) == '.') {
			s = s.substr(0, s.length - 1);
		}
	}
	var l = s.substr(0, 1) == '-';
	if (l) s = s.substr(1, s.length - 1);
	//移除左边多余的0
	while (s.length > 1 && s.substr(0, 1) == '0' && s.substr(1, 1) != '.') {
		s = s.substr(1, s.length - 1);
	}
	if (l && s != '0') s = '-' + s;
	data.value = s;
	data.minus = s.substr(0, 1) == '-';
	var ax = s.split('.');
	data.num = ax[0];
	if (ax.length > 1) {
		data.dec = ax[1];
		data.digit = ax[1].length;
	}
	data.isNum = true;
	return data;
}

/**
 * 获取文件扩展名
 * @param {String} name 文件名
 */
const getFileExt = function(name) {
	return ('' + name).toLowerCase().split('.').splice(-1).join('');
}
/**
 * 获取文件对应的图标
 * @param {String} name 文件名
 */
const getFileIco = function(name) {
	var self = this,
		ext = self.getFileExt(name);
	return ext == 'xls' || ext == 'xlsx' ? 'fa fa-file-excel-o' :
		ext == 'doc' || ext == 'docx' ? 'fa fa-file-word-o' :
		ext == 'ppt' || ext == 'pptx' ? 'fa fa-file-powerpoint-o' :
		ext == 'pdf' ? 'fa fa-file-pdf-o' :
		ext == 'txt' ? 'fa fa-file-text-o' :
		ext == 'zip' || ext == 'rar' || ext == '7z' || ext == 'tar' ? 'fa fa-file-zip-o' :
		'fa fa-files-o';
}

/**
 * 字节转 GB、KB、MB
 * @param {Number} size
 */
const getFileSize = function(size) {
	var size = Number(size);
	if (!isNaN(size) && size >= 0) {
		if (size > 1024 * 1024 * 1024) {
			return (Math.round(size * 100) / (1024 * 1024 * 1024) / 100).toFixed(2) + 'GB';
		} else if (size > 1024 * 1024) {
			return (Math.round(size * 100) / (1024 * 1024) / 100).toFixed(2) + 'MB';
		} else if (size > 1024) {
			return (Math.round(size * 100) / (1024) / 100).toFixed(2) + 'KB';
		} else {
			return size + '字节';
		}
	}
	return '';
}

/**
 * 时长转 HH:mm:ss 格式
 * @param {Number} duration
 */
const getDuration = function(duration) {
	duration = parseInt(duration);
	if (isNaN(duration) || duration <= 0) return '';
	var left = 0,
		h = '',
		m = '00',
		s = '00';
	if (duration > 60 * 60) {
		left = duration % (60 * 60);
		h = '' + ((duration - left) / (60 * 60));
		duration = left;
	}
	if (duration > 60) {
		left = duration % 60;
		m += ((duration - left) / 60);
		duration = left;
	}
	s += duration;
	return h + (h.length > 0 ? ':' : '') + m.substring(m.length - 2, m.length) + ':' + s.substring(s.length - 2, s
		.length);
}

const h5Token = function(page) {
	var app = getApp(),
		key = '';
	if (!!app.globalData.appInfo) key = app.globalData.appInfo.key;
	if (!key) {
		console.log('missing appInfo');
		return;
	}
	var currentUser = app.globalData.currentUser;
	var data = {
		appId: 8,
		key: key,
		page: page,
		time: Date.parse(new Date()) / 1000,
		uiId: !!currentUser ? currentUser.uiId : 0,
		uiType: !!currentUser ? currentUser.uiType : -1,
	};
	var word = JSON.stringify(data);
	var iv = guid(false).substr(0, 16);
	var srcs = CryptoJS.enc.Utf8.parse(word);
	var encrypted = CryptoJS.AES.encrypt(srcs, CryptoJS.enc.Utf8.parse(cfg.TK), {
		iv: CryptoJS.enc.Utf8.parse(iv),
		mode: CryptoJS.mode.CBC,
		padding: CryptoJS.pad.Pkcs7
	});
	var txt = encrypted.toString().replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
	return domain + 'wxmini/loginh5?sign=' + txt + iv;
}
const soterAuthentication = function(callback) {
	console.log('soterAuthentication')
	const startSoterAuthentication = () => {
		uni.startSoterAuthentication({
			requestAuthModes: ['fingerPrint'],
			challenge: '123456',
			authContent: '请用验证指纹',
			success(r) {
				// Notify({
				// 	type: 'success',
				// 	message: '验证成功',
				// 	duration: 1000
				// });
				var resultJSON = JSON.parse(r.resultJSON);
				return callback({
					code: 0,
					resultJSON: resultJSON,
					errmsg: ''
				});
			},
			fail(err) {
				Notify({
					type: 'danger',
					message: '认证失败：' + err.errMsg
				});
			}
		})
	}
	const checkIsEnrolled = () => {
		uni.checkIsSoterEnrolledInDevice({
			checkAuthMode: 'fingerPrint',
			success(r) {
				console.log(r);
				if (!r.isEnrolled) {
					Notify({
						type: 'danger',
						message: '您的手机暂未录入指纹信息，请录入后重试'
					});
					return;
				};
				startSoterAuthentication();
			},
			fail(err) {
				Notify({
					type: 'danger',
					message: '获取是否录入指纹失败：' + err.errMsg
				});
			}
		})
	}
	uni.checkIsSupportSoterAuthentication({
		success(ret) {
			if (ret.supportMode.findIndex(function(g) {
					return g == "fingerPrint"
				}) <= -1) {
				return callback({
					code: false,
					resultJSON: null,
					errmsg: '该设备不支持指纹验证'
				});
			};
			checkIsEnrolled();
		},
		fail(err) {
			Notify({
				type: 'danger',
				message: '获取本机支持的认证方式失败：' + err.errMsg
			});
			return callback({
				code: 1,
				resultJSON: null,
				errmsg: err.errMsg
			});
		}
	});

};
/**
 * 检查用户权限
 * @param {Number} duration
 */
const canDo = function(id) {
	const app = getApp();
	var obj = app.globalData.currentUser.uiAccessList.find(function(item) {
		return item.flId == id;
	});
	return !!obj ? true : false;
}
module.exports = {
	canDo,
	loading,
	log,
	domain,
	config,
	guid,
	trim,
	isFunction,
	isArray,
	isMobile,
	createNumCode,
	ToMd5,
	showLoading,
	hideLoading,
	alert,
	confirm,
	toast,
	toastOK,
	toastERR,
	post,
	uploadfile,
	getAppInfo,
	getUserDes,
	formatBit,
	formatSeconds,
	formatSize,
	formatDateTime,
	addToDate,
	findIndex,
	find,
	findItems,
	extend,
	checkSchoolSets,
	dateFormat,
	dateFormat1,
	hasAccessID,
	Notify,
	success,
	error,
	base64Encode,
	base64Decode,
	getPhoneType,
	isEmail,
	isIdentityCode,
	dateAdd,
	dateConfig,
	timestampToTime,
	wxBrokerage,
	formatNum,
	getFileExt,
	getFileIco,
	getFileSize,
	getDuration,
	h5Token,
	soterAuthentication,
	toDate
};